The basics of collecting and reading extended events data
The basic steps to use Extended Events are as follows:- Create an Extended Events session
- Add events to the Extended Events session
- Add actions to the Extended Events session
- Add filters
- Add a target for event data
- Specify options
- Start the Extended Events session
- Periodically read data from the Extended Events session
Creating an Extended Events session
Creating a new Extended Events session via T-SQL involves deciding up-front how to configure and run it. Typically, filters, events, and options will be tweaked afterwards as the resulting data is reviewed and a better idea of how it should look is envisioned. The following is the most bare-bones way to create an Extended Events session:|
1 2 3 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed; |
|
1 2 3 4 |
SELECT * FROM sys.server_event_sessions WHERE server_event_sessions.name = 'Sql_Server_Query_Metrics'; |
Note the value of 0 provided by startup_state, which indicates that the Extended Events session exists but is stopped.
The view sys.dm_xe_sessions can also be used to check for the existence of active Extended Events sessions:
|
1 2 3 4 |
SELECT * FROM sys.dm_xe_sessions WHERE dm_xe_sessions.name = 'Sql_Server_Query_Metrics'; |
The lack of rows returned is another way to confirm that this session is not started.
Creating an Extended Events session with no additional parameters is not a good idea. It is good practice to provide as much detail as possible about the target, events, actions, filters, and options.
Add events to the Extended Events session
An event is a response to a specific triggered occurrence in SQL Server. It could be a deadlock, a completed query, or a user login. All of the available events in SQL Server can be browsed via system views:|
1 2 3 |
SELECT * FROM sys.dm_xe_packages; |
This query returns a list of all events. Note that the view dm_xe_objects also contains types, targets, actions, and other entities, as given by the column object_type.
|
1 2 3 4 5 6 7 8 9 10 |
SELECT dm_xe_packages.name AS package_name, dm_xe_packages.description, dm_xe_objects.name AS object_name, dm_xe_objects.object_type, dm_xe_objects.description FROM sys.dm_xe_objects INNER JOIN sys.dm_xe_packages ON dm_xe_packages.guid = dm_xe_objects.package_guid WHERE dm_xe_objects.object_type = 'event'; |
At least one event is required for an Extended Events session, but multiple may be added like this:
|
1 2 3 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed, ADD EVENT sqlserver.sql_batch_completed; |
Add actions to the Extended Events session
Several data points are automatically collected for each event type. Actions allow additional elements to be retrieved along with their respective event, thereby customizing events with data that does not need to be retrieved by default for all use-cases. Actions are added onto events like this:|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username)), ADD EVENT sqlserver.sql_batch_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username)); |
Add filters to the Extended Events session
Filters allow results to be limited to those required for the monitoring/troubleshooting task at hand. They remove extraneous results and decrease the size of the extended event payload data, which will make consumption of that data faster and more efficient. Filters are added as WHERE clauses onto each event:|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')), ADD EVENT sqlserver.sql_batch_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')); |
Add a target to the extended events session
Event data needs to be written somewhere, and that somewhere needs to have the resources to accept whatever volume of data will originate from a given Extended Events Session. A complete list of all target types is available here: Targets for Extended Events in SQL Server – SQL Server | Microsoft Docs While that list is long, most users of Extended Events will use either the ring buffer or a file as the target for their event output. The rest are worth reviewing to gain knowledge and to understand what else is available but are typically used for less common tasks. The ring buffer stores events in memory and will automatically clear itself out as a memory cap is reached or if a maximum event count is reached. The ring buffer is great for testing Extended Events and developing new code, but is not ideal for production workloads, especially larger ones. A ring buffer target can be specified like this:|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')), ADD EVENT sqlserver.sql_batch_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')) ADD TARGET package0.ring_buffer ( SET max_memory = 2000, -- 2000kb max_events_limit = (500)); |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')), ADD EVENT sqlserver.sql_batch_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')) ADD TARGET package0.event_file (SET FILENAME = 'C:\SQLBackup\Sql_Server_Query_Metrics.xel', MAX_FILE_SIZE = 1000, -- 1000MB MAX_ROLLOVER_FILES = 3); |
Specify options for an Extended Events session
The last step in configuring an Extended Events session is to set options that determine how events are captured, stored, and maintained. The following is an example of a few options that are added to the growing demonstration from above:|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
CREATE EVENT SESSION Sql_Server_Query_Metrics ON SERVER ADD EVENT sqlserver.rpc_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')), ADD EVENT sqlserver.sql_batch_completed ( ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.session_id, sqlserver.username) WHERE (sqlserver.client_app_name NOT LIKE 'SQLAgent%')) ADD TARGET package0.event_file (SET FILENAME = 'C:\SQLBackup\Sql_Server_Query_Metrics.xel', MAX_FILE_SIZE = 1000, -- 1000MB MAX_ROLLOVER_FILES = 3) WITH ( EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY = 15 SECONDS, MAX_MEMORY = 1024MB, STARTUP_STATE = OFF); |
Start the Extended Events session
Assuming STARTUP_STATE = OFF when the event session is created, the session will need to be started. This can be done with the following T-SQL:|
1 2 |
ALTER EVENT SESSION Sql_Server_Query_Metrics ON SERVER STATE = START; |
|
1 2 |
ALTER EVENT SESSION Sql_Server_Query_Metrics ON SERVER STATE = STOP; |
Read data from the Extended Events session file
The work thus far relies on the ability to quickly read data from an Extended Events session. This is by far the most challenging part of using Extended Events. The target data is written as XML and effectively making use of it requires XML parsing. SQL Server provides a function that can be used to read directly from this XML data called sys.fn_xe_file_target_read_file. This is how a query using this function will look:|
1 2 3 4 5 |
SELECT timestamp_utc AS sample_time_utc, CAST(event_data AS VARCHAR(MAX)) AS event_data_xml FROM sys.fn_xe_file_target_read_file( 'C:\SQLBackup\Sql_Server_Query_Metrics.xel', NULL, NULL, NULL); |
That was disappointing! The file name used for the file target will have additional numbers appended to it to allow it to differentiate files used for the event session. This is necessary if rollover files are used as multiple files cannot share the same name. Details about the file can be returned with a query against sys.server_event_session_fields:
|
1 2 3 4 5 6 7 |
SELECT * FROM sys.server_event_session_fields INNER JOIN sys.server_event_sessions ON server_event_sessions.event_session_id = server_event_session_fields.event_session_id WHERE server_event_sessions.name = 'Sql_Server_Query_Metrics'; |
Note that the file name provided here does not match the physical file name but the name provided when the event session was created. The physical file looks like this:
The function fn_xe_file_target_read_file can include wild cards, so there is no need to fish around for the exact physical file name:
|
1 2 3 4 5 |
SELECT timestamp_utc AS sample_time_utc, CAST(event_data AS VARCHAR(MAX)) AS event_data_xml FROM sys.fn_xe_file_target_read_file( 'C:\SQLBackup\Sql_Server_Query_Metrics*.xel', NULL, NULL, NULL); |
Retrieved are the timestamp and a big glob of XML. It is generally faster to store this data as XML and parse it asynchronously at a later time or as part of a structured process. XML shredding takes time and potentially hefty computing resources, so waiting on it is not ideal.
It is important to note that for exceptionally high event volume, the fastest way to process the XML is to use PowerShell or a .NET application to directly read the XEL file. Doing that here is well out of scope for this article but is an exercise undertaken by others in the community and worth investigating if all else fails.
Extended Events data collection
It is here that this work moves from building blocks into building. This article has provided an overview of creating, configuring, and pulling data from Extended Events sessions. To go further, permanent database objects will need to be created to manage and store the XML and the event data derived from it. Extended Events are highly customizable and versatile. Therefore, efforts to build a process that uses the content discussed thus far will benefit from flexibility. There are many, many ways to solve this challenge, and each database environment will benefit from slightly different approaches. There is a great benefit in using T-SQL exclusively to implement and manage Extended Events. While the SQL Server Management Studio UI is convenient, it is not a scalable approach for large numbers of database servers. Therefore, I encourage the reader to pursue using T-SQL, regardless of the simplicity or complexity of event collection needs. The next article will combine the concepts presented here into a more permanent solution that can be tailored to a wide variety of SQL Server monitoring and data collection challenges. If you liked this article, you might also like Collecting SQL Server performance monitor data – Simple Talk (red-gate.com).FAQs
1. What are SQL Server Extended Events?
SQL Server Extended Events (XEvents) is a lightweight, configurable event-capture framework introduced in SQL Server 2008 that replaced SQL Trace and SQL Server Profiler for diagnostic monitoring. Extended Events sessions capture specific events (query execution, deadlocks, wait types, memory allocations, errors) and route them to targets (in-memory ring buffer, on-disk event_file, histogram, pair_matching, event_counter) for analysis. The framework is designed to be low-overhead by default, extensible (new events are added in each SQL Server release), and scriptable (entire sessions can be created, managed, and queried via T-SQL). Extended Events is the only monitoring framework Microsoft actively develops – SQL Profiler remains functional but is deprecated for most use cases.
2. How do I create a SQL Server Extended Events session?
Use CREATE EVENT SESSION with clauses defining the events, actions, predicates, targets, and options. Minimal syntax: CREATE EVENT SESSION [MySession] ON SERVER ADD EVENT sqlserver.sql_statement_completed ADD TARGET package0.event_file (SET filename = ‘C:\XE\MySession.xel’) WITH (STARTUP_STATE = OFF). Then ALTER EVENT SESSION [MySession] ON SERVER STATE = START to begin capture. Add ACTION clauses inside ADD EVENT to capture additional context per event (session_id, client_app_name, sql_text, etc.). Add WHERE clauses inside ADD EVENT to filter what’s captured. Multiple targets can be added to a single session when you need different views of the same data (for example, a ring_buffer for live inspection plus an event_file for persistent history).
3. How do I read data from an Extended Events event_file target?
Query sys.fn_xe_file_target_read_file passing the file path pattern – this returns the raw XML event_data. Shred the XML with nodes() and value() to extract specific fields: SELECT event_data.value(‘(event/@name)[1]’, ‘nvarchar(100)’) AS event_name, event_data.value(‘(event/@timestamp)[1]’, ‘datetime2’) AS timestamp, event_data.value(‘(event/data[@name=”duration”]/value)[1]’, ‘bigint’) AS duration_microseconds FROM (SELECT CAST(event_data AS XML) AS event_data FROM sys.fn_xe_file_target_read_file(‘C:\XE\MySession*.xel’, NULL, NULL, NULL)) AS e. For large files this can be slow – the XML shred is the typical bottleneck in Extended Events analysis. For routine reporting, stage the shredded events into a table once and query the table.
4. Are SQL Server Extended Events replacing SQL Profiler?
Yes – Extended Events has replaced SQL Profiler as the recommended monitoring framework since SQL Server 2012. SQL Profiler and SQL Trace remain available for backwards compatibility but are deprecated and receive no new functionality. Extended Events offers equivalent or broader event coverage with substantially lower overhead, more flexible targets (including histograms and pair-matching for specialised analysis), and better integration with Azure SQL Database (where Profiler doesn’t work at all). Most tasks that used Profiler – capturing long queries, finding deadlocks, tracing a specific login’s activity – have a direct Extended Events equivalent. If you’re currently using Profiler for new monitoring work, migrate to Extended Events; existing Profiler traces can run until you’re ready.
This document contains proprietary information and is protected by copyright law.
Copyright © 2026 Red Gate Software Limited. All rights reserved
Load comments